/* -----------------------------------------------------------------------
 * Include the following lines in your makefile:
 *
 * unittest1: unittest1.c dominion.o rngs.o
 *      gcc -o unittest1 -g  unittest1.c dominion.o rngs.o $(CFLAGS)
 * -----------------------------------------------------------------------
 */

#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"

// set NOISY_TEST to 0 to remove printfs from output
#define NOISY_TEST 1

// set BOUNDARY_TEST to 0 to exclude boundary test cases.
#define BOUNDARY_TEST 0

int main() {
    int r, p;
    int seed = 1000;
    int k[10] = {adventurer, council_room, feast, gardens, mine
               , remodel, smithy, village, baron, great_hall};
    struct gameState G;
    int curse_count, estate_count, duchy_count, province_count, copper_count, silver_count, gold_count;

    printf ("TESTING initializeGame():\n");
    for (p = 2; p <= MAX_PLAYERS; p++)
    {
	  	//set variable values
	  	switch(p){
	  	case 2:
	  		curse_count = 10;
	  		estate_count = 8;
	  		duchy_count = 8;
	  		province_count = 8;
	  		copper_count = 60 - (7 * p);
	  		silver_count = 40;
	  		gold_count = 30;
	  		break;
	  		
	  	case 3:
	  		curse_count = 20;
	  		estate_count = 12;
	  		duchy_count = 12;
	  		province_count = 12;
	  		copper_count = 60 - (7 * p);
	  		silver_count = 40;
	  		gold_count = 30;	  	
	  		break;
	  		
	  	case 4:
	  		curse_count = 30;
	  		estate_count = 12;
	  		duchy_count = 12;
	  		province_count = 12;
	  		copper_count = 60 - (7 * p);
	  		silver_count = 40;
	  		gold_count = 30;	  	
	  		break;
	  		
	  	default:
		  	curse_count = 30;
	  		estate_count = 12;
	  		duchy_count = 12;
	  		province_count = 12;
	  		copper_count = 60 - (7 * p);
	  		silver_count = 40;
	  		gold_count = 30;
	  		break;
	  	}
    	memset(&G, 23, sizeof(struct gameState));   // clear the game state
        r = initializeGame(p, k, seed, &G); // initialize a new game

#if (NOISY_TEST == 1)
        printf("Test game with %d players.\n", p);
#endif

#if (NOISY_TEST == 1)
        printf("Curse cards = %d, expected = %d\n", G.supplyCount[curse], curse_count);
#endif
        assert(G.supplyCount[curse] == curse_count); // check if the number of curse cards is correct

#if (NOISY_TEST == 1)
        printf("Estate cards = %d, expected = %d\n", G.supplyCount[estate], estate_count);
#endif
        assert(G.supplyCount[estate] == estate_count); // check if the number of estate cards is correct

#if (NOISY_TEST == 1)
        printf("Duchy cards = %d, expected = %d\n", G.supplyCount[duchy], duchy_count);
#endif
        assert(G.supplyCount[duchy] == duchy_count); // check if the number of duchy cards is correct                        

#if (NOISY_TEST == 1)
        printf("Province cards = %d, expected = %d\n", G.supplyCount[province], province_count);
#endif
        assert(G.supplyCount[province] == province_count); // check if the number of province cards is correct                        

#if (NOISY_TEST == 1)
        printf("Copper cards = %d, expected = %d\n", G.supplyCount[copper], copper_count);
#endif
        assert(G.supplyCount[copper] == copper_count); // check if the number of copper cards is correct  
    
#if (NOISY_TEST == 1)
        printf("Silver cards = %d, expected = %d\n", G.supplyCount[silver], silver_count);
#endif
        assert(G.supplyCount[silver] == silver_count); // check if the number of silver cards is correct  
    
#if (NOISY_TEST == 1)
        printf("Gold cards = %d, expected = %d\n", G.supplyCount[gold], gold_count);
#endif
        assert(G.supplyCount[gold] == gold_count); // check if the number of gold cards is correct  
    }

    printf("All domain tests passed!\n");
    
#if (BOUNDARY_TEST == 1)
    printf("Testing boundary cases.\n");

	p = 0;    
#if (NOISY_TEST == 1)
    printf("Testing player = %d\n", p);
#endif

	//default card counts
	curse_count = 30;
	estate_count = 12;
	duchy_count = 12;
	province_count = 12;
	copper_count = 60 - (7 * p);
	silver_count = 40;
	gold_count = 30;
	
	memset(&G, 23, sizeof(struct gameState));   // clear the game state
    r = initializeGame(p, k, seed, &G); // initialize a new game
	
	#if (NOISY_TEST == 1)
        printf("Curse cards = %d, expected = %d\n", G.supplyCount[curse], curse_count);
#endif
        assert(G.supplyCount[curse] == curse_count); // check if the number of curse cards is correct

#if (NOISY_TEST == 1)
        printf("Estate cards = %d, expected = %d\n", G.supplyCount[estate], estate_count);
#endif
        assert(G.supplyCount[estate] == estate_count); // check if the number of estate cards is correct

#if (NOISY_TEST == 1)
        printf("Duchy cards = %d, expected = %d\n", G.supplyCount[duchy], duchy_count);
#endif
        assert(G.supplyCount[duchy] == duchy_count); // check if the number of duchy cards is correct                        

#if (NOISY_TEST == 1)
        printf("Province cards = %d, expected = %d\n", G.supplyCount[province], province_count);
#endif
        assert(G.supplyCount[province] == province_count); // check if the number of province cards is correct                        

#if (NOISY_TEST == 1)
        printf("Copper cards = %d, expected = %d\n", G.supplyCount[copper], copper_count);
#endif
        assert(G.supplyCount[copper] == copper_count); // check if the number of copper cards is correct  
    
#if (NOISY_TEST == 1)
        printf("Silver cards = %d, expected = %d\n", G.supplyCount[silver], silver_count);
#endif
        assert(G.supplyCount[silver] == silver_count); // check if the number of silver cards is correct  
    
#if (NOISY_TEST == 1)
        printf("Gold cards = %d, expected = %d\n", G.supplyCount[gold], gold_count);
#endif
        assert(G.supplyCount[gold] == gold_count); // check if the number of gold cards is correct  

	p = MAX_PLAYERS + 1;
        
#if (NOISY_TEST == 1)
    printf("Testing player = %d\n", p);
#endif
	//default card counts
	curse_count = 30;
	estate_count = 12;
	duchy_count = 12;
	province_count = 12;
	copper_count = 60 - (7 * p);
	silver_count = 40;
	gold_count = 30;
	
	memset(&G, 23, sizeof(struct gameState));   // clear the game state
    r = initializeGame(p, k, seed, &G); // initialize a new game
	
	#if (NOISY_TEST == 1)
        printf("Curse cards = %d, expected = %d\n", G.supplyCount[curse], curse_count);
#endif
        assert(G.supplyCount[curse] == curse_count); // check if the number of curse cards is correct

#if (NOISY_TEST == 1)
        printf("Estate cards = %d, expected = %d\n", G.supplyCount[estate], estate_count);
#endif
        assert(G.supplyCount[estate] == estate_count); // check if the number of estate cards is correct

#if (NOISY_TEST == 1)
        printf("Duchy cards = %d, expected = %d\n", G.supplyCount[duchy], duchy_count);
#endif
        assert(G.supplyCount[duchy] == duchy_count); // check if the number of duchy cards is correct                        

#if (NOISY_TEST == 1)
        printf("Province cards = %d, expected = %d\n", G.supplyCount[province], province_count);
#endif
        assert(G.supplyCount[province] == province_count); // check if the number of province cards is correct                        

#if (NOISY_TEST == 1)
        printf("Copper cards = %d, expected = %d\n", G.supplyCount[copper], copper_count);
#endif
        assert(G.supplyCount[copper] == copper_count); // check if the number of copper cards is correct  
    
#if (NOISY_TEST == 1)
        printf("Silver cards = %d, expected = %d\n", G.supplyCount[silver], silver_count);
#endif
        assert(G.supplyCount[silver] == silver_count); // check if the number of silver cards is correct  
    
#if (NOISY_TEST == 1)
        printf("Gold cards = %d, expected = %d\n", G.supplyCount[gold], gold_count);
#endif
        assert(G.supplyCount[gold] == gold_count); // check if the number of gold cards is correct  
        
    printf("All boundary tests passed!\n");   
    
#endif 
        
    return 0;
}
